package com.rytx.web.controller.kd100;

import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.kuaidi100.sdk.api.QueryTrack;
import com.kuaidi100.sdk.api.Subscribe;
import com.kuaidi100.sdk.contant.ApiInfoConstant;
import com.kuaidi100.sdk.contant.CompanyConstant;
import com.kuaidi100.sdk.core.IBaseClient;
import com.kuaidi100.sdk.pojo.HttpResult;
import com.kuaidi100.sdk.request.*;
import com.kuaidi100.sdk.response.SubscribePushData;
import com.kuaidi100.sdk.response.SubscribePushParamResp;
import com.kuaidi100.sdk.response.SubscribePushResult;
import com.kuaidi100.sdk.response.SubscribeResp;
import com.kuaidi100.sdk.utils.SignUtils;
import com.rytx.common.config.KuaiDi100Config;
import com.rytx.common.core.controller.BaseController;
import com.rytx.common.core.domain.AjaxResult;
import com.rytx.common.utils.DateUtils;
import com.rytx.common.utils.StringUtils;
import com.rytx.system.domain.ArtKd100;
import com.rytx.system.domain.dto.SetCourier;
import com.rytx.system.domain.ysp.ArtOrder;
import com.rytx.system.service.IArtKd100Service;
import com.rytx.system.service.IArtOrderService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

@RestController
@RequestMapping("/kd100")
public class KuaiDi100Controller extends BaseController {
    @Resource
    private IArtKd100Service artKd100Service;
    @Resource
    private IArtOrderService artOrderService;
    @Resource
    private KuaiDi100Config kd100Config;
    @Resource
    private Gson gson;


    public void test(SetCourier setCourier){
        artKd100Service.subscribe( setCourier);
    }

    @PostMapping("/subscribe")
    public AjaxResult subscribe(@RequestBody SetCourier setCourier){
        try {
            logger.info("快递100订阅参数|{}|{}|{}",setCourier.getKdCompany(),setCourier.getKdNumber(),setCourier.getPhone());
            if("shunfeng".equals(setCourier.getKdCompany())||"shunfengkuaiyun".equals(setCourier.getKdCompany())){
                if (StringUtils.isBlank(setCourier.getPhone())) {
                    return AjaxResult.error("顺丰快递必须填写手机号码");
                }
            }
            String orderNo = setCourier.getOrderNo();
            if(StringUtils.isEmpty(orderNo)){
                return AjaxResult.error("请填写订单号");
            }
            String kdNumber = setCourier.getKdNumber();
            if(StringUtils.isEmpty(kdNumber)){
                return AjaxResult.error("请填写运单号");
            }
            String kdCompany = setCourier.getKdCompany();
            if(StringUtils.isEmpty(kdCompany)){
                return AjaxResult.error("请选择快递公司");
            }
            ArtOrder orderByOrderNo = artOrderService.getOrderByOrderNo(orderNo);
            if(orderByOrderNo == null){
                return AjaxResult.error("未找到订单");
            }
            SubscribeParam subscribeParam = getSubscribeParam(setCourier);

            SubscribeReq subscribeReq = new SubscribeReq();
            subscribeReq.setSchema(ApiInfoConstant.SUBSCRIBE_SCHEMA);
            subscribeReq.setParam(gson.toJson(subscribeParam));

            IBaseClient subscribe = new Subscribe();
            HttpResult execute = subscribe.execute(subscribeReq);
            String body = execute.getBody();
            JSONObject jsonObject = JSONObject.parseObject(body);
            Boolean result = jsonObject.getBoolean("result");
            if(!result){
                return AjaxResult.error(jsonObject.getString("message"));
            }
            logger.info("快递100订阅结果|{}",execute.getBody());
            ArtOrder update = new ArtOrder();
            update.setOrderNo(orderNo);
            update.setLogisticsName(setCourier.getKdCompanyName());
            update.setLogisticsNo(setCourier.getKdNumber());
           /* update.setLogisticsRemark(setCourier);*/
            update.setLogisticsCode(setCourier.getKdCompany());
            update.setDeliveryDate(new Date());
            artOrderService.updateByOrderNo(update);
            return AjaxResult.success(execute.getBody());
        } catch (Exception e) {
            logger.error("快递100订阅失败",e);
            return AjaxResult.error("快递100订阅失败");
        }
    }

    private SubscribeParam getSubscribeParam(SetCourier setCourier) {
        SubscribeParameters subscribeParameters = new SubscribeParameters();
        subscribeParameters.setCallbackurl(kd100Config.getNotifyUrl());
        subscribeParameters.setSalt(kd100Config.getSalt());
        subscribeParameters.setPhone(setCourier.getPhone());//shunfeng shunfengkuaiyun  顺丰速运、顺丰快运必填

        SubscribeParam subscribeParam = new SubscribeParam();
        subscribeParam.setParameters(subscribeParameters);
        subscribeParam.setCompany(setCourier.getKdCompany());//CompanyConstant.ST sdk包自带的快递公司编码
        subscribeParam.setNumber(setCourier.getKdNumber());
        subscribeParam.setKey(kd100Config.getKey());
        return subscribeParam;
    }

    @PostMapping("/queryTrack")
    public AjaxResult queryTrack(@RequestBody String company, String num,String phone) throws Exception{
        if("shunfeng".equals(company)||"shunfengkuaiyun".equals(company)){
            if(StringUtils.isBlank(phone)){
                return AjaxResult.error("顺丰快递必须填写手机号码");
            }
        }

        // 创建查询物流请求对象
        QueryTrackReq queryTrackReq = new QueryTrackReq();
        // 创建查询物流参数对象
        QueryTrackParam queryTrackParam = new QueryTrackParam();
        // 设置物流公司为YT
        queryTrackParam.setCom(CompanyConstant.YT);
        // 设置物流单号
        queryTrackParam.setNum(num);
        // 设置收货人手机号码
        queryTrackParam.setPhone(phone);//shunfeng shunfengkuaiyun 顺丰速运、顺丰快运必填
        // 将查询物流参数对象转换为JSON字符串
        String param = gson.toJson(queryTrackParam);
        // 将JSON字符串设置为查询物流请求的参数
        queryTrackReq.setParam(param);
        // 设置查询物流请求的客户编号
        queryTrackReq.setCustomer(kd100Config.getCustomer());
        // 生成签名并设置为查询物流请求的签名
        queryTrackReq.setSign(SignUtils.querySign(param ,kd100Config.getKey(),kd100Config.getCustomer()));
        // 创建查询物流的客户端对象
        IBaseClient baseClient = new QueryTrack();
        // 执行查询物流请求并打印结果
        return AjaxResult.success(baseClient.execute(queryTrackReq));
    }
    @PostMapping("/callback")
    public void callback(HttpServletRequest request, HttpServletResponse response) throws Exception{

        /*Map<String, String> paramMap = getParamMap(request);
        logger.info("快递100订阅推送数据|{}", JSONObject.toJSONString(paramMap));*/


        String param = request.getParameter("param");
        String sign = request.getParameter("sign");
        logger.info("快递100订阅推送回调结果|{}|{}",param,sign);
        //订阅时传的salt,没有可以忽略
        String salt = kd100Config.getSalt();
        String ourSign = SignUtils.sign(param + salt);
        //加密如果相等，属于快递100推送；否则可以忽略掉当前请求
        if (ourSign.equals(sign)){
            logger.info("快递100订阅推送验签结果|{}",true);
            //TODO 业务处理

            SubscribePushParamResp sppr = gson.fromJson(param, SubscribePushParamResp.class);
            sppr.getStatus();
            SubscribePushResult lastResult = sppr.getLastResult();
            String nu = lastResult.getNu();
            String com = lastResult.getCom();
            String message = sppr.getMessage();
            //监控状态:polling:监控中，shutdown:结束，abort:中止，updateall：重新推送。其中当快递单为已签收时status=shutdown，当message为“3天查询无记录”或“60天无变化时
            //”status= abort ，对于status=abort的状态，需要增加额外的处理逻辑
            String status = sppr.getStatus();
            String ischeck = lastResult.getIscheck();
            List<SubscribePushData> data = lastResult.getData();
            ArtKd100 select = artKd100Service.getKd100ByNo(nu,com);

            //这里处理一下订单中的签收时间，并且根据签收时间计算租赁时间 和租赁结束时间
            if("1".equals(ischeck)){//如果已经签收
                ArtOrder artOrder =   artOrderService.getOrderByNu(nu,com);
                if(null!= artOrder){
                    // 租赁订单
                    if(artOrder.getRentalDays() != null && "1".equals(artOrder.getOrderType())) {
                    Date signDate = artOrder.getSignDate();//签收时间

                        if(null == signDate){//如果签收时间为空才去计算
                            //得到签收时间
                            int size = data.size();
                            if(size>0){
                                ArtOrder update = new ArtOrder();
                                update.setId(artOrder.getId());

                                SubscribePushData subscribePushData = data.get(0);
                                String ftime = subscribePushData.getFtime();//这里的格式是 2024-08-28 12:23:20
                                Date signTime = DateUtils.dateTime(DateUtils.YYYY_MM_DD,ftime);//数据库是日期格式
                                Calendar calendar = Calendar.getInstance();
                                calendar.setTime(signTime);
                                update.setRentalStartDate(signTime); // 租赁开始日期

                                calendar.add(Calendar.MONTH, artOrder.getRentalDays());
                                Date endDate = calendar.getTime();

                                update.setRentalEndDate(endDate); // 租赁结束日期
                                update.setSignDate(signTime); // 签收时间
                                artOrderService.updateArtOrderSignDate(update);
                            }
                        }
                    }
                }
            }

            if(null!= select){//修改
                // ArtOrder artOrder = artOrderService.selectArtOrderById();
                // 先根据快递单号查询对应记录
                select.setStatus(status);
                select.setCom(com);
                select.setNu(nu);
                select.setMessage(message);
                select.setIscheck(ischeck);
                select.setResData(param);
                select.setLogistics(JSONObject.toJSONString(data));
                select.setCreateTime(new Date());
                artKd100Service.updateArtKd100(select);
            }else{
                ArtKd100 artKd100 = new ArtKd100();
                // artKd100.setOrderId(artOrder.getId());
                /*artKd100.setRespJson(param);*/
                artKd100.setStatus(status);
                artKd100.setCom(com);
                artKd100.setNu(nu);
                artKd100.setMessage(message);
                artKd100.setIscheck(ischeck);
                artKd100.setResData(param);
                artKd100.setLogistics(JSONObject.toJSONString(data));
                artKd100.setCreateTime(new Date());
                artKd100Service.insertArtKd100(artKd100);
            }



        }else{
            logger.info("快递100订阅推送回调签名验证失败|{}|{}",param,sign);
        }
      // 快递100需要的返回格式： { "result":true, "returnCode":"200", "message":"成功" }
        SubscribeResp subscribeResp = new SubscribeResp();
            subscribeResp.setResult(Boolean.TRUE);
            subscribeResp.setReturnCode("200");
            subscribeResp.setMessage("成功");
        response.getWriter().write(gson.toJson(subscribeResp));
    }

    private Map<String,String> getParamMap(HttpServletRequest request){
        try (InputStream inputStream = request.getInputStream()) {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(inputStream, Map.class);
        } catch (IOException e) {
            throw new RuntimeException("Error reading request body", e);
        }
    }
}
